<?php
/**
 * 订单处理model
 */
namespace app\v2\model;
use think\Model;
use think\Db;
use app\common\model\HcPay;
use app\v2\controller\Script;
use fuiou\FuiouApi;
use app\v2\model\UserBankCard;
use think\cache\driver\Redis;
use app\v2\model\User;

class Order extends Model 
{	
    
    protected $name = 'user_order';
    protected $createTime = false;
	protected $updateTime = false;

    /**
     * 创建订单
     * @author   yhq <934797303@qq.com>
     * @Date 2017-09-29
     * @param    [type]                   $uid [description]
     * @return   [type]                        [description]
     */
    public function createorder($param) {
        if(empty($param['pay_type']) || empty($param['order_number']) || empty($param['pay_money']) || (empty($param['pay_password']) && $param['repay_type'] === 1)){
            $this->error = '缺少参数';
            return false;
        }
        
        // Redis锁验证
        $redis    = new Redis();
        $redisKey = config('project_name').":createorder_".$param['order_number'];
        $redis -> select(config('redis_select'));
        if(false!==$redis->get($redisKey)){
            $this->error = '请稍候重试';
            return false;
        }
        
        // 逾期处理中 禁止支付
        $script = new Script;
        $order_number = $param['order_number'];
        $canCreatePayOrder = $script->canCreatePayOrder($order_number);
        if($canCreatePayOrder['code'] != 1){
            $this->error = $canCreatePayOrder['msg'];
            return false;
        }

        $ApplyModel = new Apply();
        $UserInfoModel = new UserInfo();
        $UserModel = new User();
        $map['order_number'] = $param['order_number'];
        $map['status'] = array('in' , [1,2,3,4,12]);
    	$res = $ApplyModel->where($map)->find();
    	if(!$res){
    		$this->error = '暂无还款数据';
    		return false;
    	}
        $res = $res->toArray();
        // 限制当天申请还款
        if(date('Ymd',SYS_TIMESTAMP) == date('Ymd',strtotime($res['fk_time']))  && $param['pay_type']=='1'){
            $this->error="不足一日，请次日申请";
            return false;
        }

        $reg_time = $UserModel->where('uid',$res['uid'])->value('reg_time'); //用户注册时间

        $res['reg_time'] = date('YmdHis',strtotime($reg_time)); //用户注册时间格式化
        $res['no_agree'] = $param['no_agree'];  //协议号
        $res['create_time'] = date('Y-m-d H:i:s');  //创建时间
        $res['order_number'] = $ApplyModel->order_number();
        //特殊情况 档位会变，正在查找原因中......
        if($res['money'] < $res['loan_out_money'])
        {
            $this->error = '订单异常，请联系客服';
            return false;
        }
        switch ($param['pay_type']) {
            case '1': //全额还款
                $arr = $ApplyModel->loanMoney($res);
                break;
            case '2': //延期
                if(empty($param['days'])){
                    $this->error="缺少参数:days";
                    return false;
                }else if($res['zhangqi']==1 && $param['days']==7){
                    $this->error='不能重复展期';
                    return false;
                }
                $arr = $ApplyModel->delayMoney($res, $param['days']);
                break;
            case '3': //部分还款
                $gearModel    = new Gear;
                $apply_status = $gearModel->apply_status($res);
                if($apply_status['part']!=1){
                    $this->error = '逾期后才能部分还款';
                    return false;  
                }
                $arr = $ApplyModel->loanMoney($res);
                if($arr['money_order'] < 100 && $param['pay_money'] != $arr['money_order']){
                    $this->error = '金额过少不支持修改';
                    return false; 
                }
                if($arr['money_order'] > 100 && $param['pay_money'] < 100) {
                    $this->error = '金额不能少于100';
                    return false; 
                }
                if($param['pay_money'] > $arr['money_order']){
                    $this->error = '大于应还金额';
                    return false; 
                }
                $arr['money_order'] = $param['pay_money'];
                $arr['info_order'] = '部分还款';
                break;
            default:
                $this->error = '参数错误:pay_type';
                return false; 
                break;
        }
        //换卡支付
        if(!empty(isset($param['bank_id'])))
        {
            $userBankCard = new UserBankCard;
            $cardInfo = $userBankCard->getCard(['id' => $param['bank_id']],'uid,bank_card_number');
            if($cardInfo['uid'] != $res['uid'])
            {
                $this->error = '绑卡人与卡号不一致';
                return false;
            }
            $res['bank_card_number'] = $cardInfo['bank_card_number'];

        }
        // 订单号去重
        $count = $this->where('no_order', $arr['no_order'])->count();
        if($count>0){
            $this->error = '数据异常，请重试';
            return false;
        }

        $res['money_order'] = (string)$arr['money_order'];  //金额
        $res['info_order']  = $arr['info_order'];   //描述
        $res['no_order']    = $arr['no_order'];    //支付订单号

        if($param['pay_money'] != $res['money_order']){
            $this->error = '数据异常，请刷新页面重试';
            return false;
        }
        
        $UserInfo = $UserInfoModel->where('uid',$res['uid'])->field('rand_code')->find();
        $res['rand_code'] = $UserInfo['rand_code'];
		/*$PayModel =  new Pay();
		$getLlPay = $PayModel->getLlPay($res);
		if(!$getLlPay){
			$this->error = '订单创建失败';
			return false;
		}*/
        //还款方式 0 支付宝 1 富友
        $param['repay_type'] = $param['repay_type'] ?: 0;
        if($param['repay_type'] != 1)
        {
            //调用支付宝支付
            $hp = new HcPay;
            $data = $hp->aliPay($res);
            if(!$data)
            {
                $this->error = $hp->getError();
                return false;
            }
        }else{
            # 校验支付密码
            if(!$UserModel->checkPayPassword($res['uid'], $param['pay_password'])){
                $this->error = $UserModel->getError();
                return false;
            }
            //富友支付  项目录入
            $re = $this->getFuiouProjectParam($res);
            $fuiouApi = new FuiouApi;
            $projectRes = $fuiouApi->project($re);
            $projectRes = json_decode($projectRes,true);
            //项目录入成功
            if($projectRes['ret'] == '0000')
            {
                $res['project_id'] = $projectRes['project_id'];
                //返回订单号
                $data = $res['no_order'];
            }else{
                $this->error = $projectRes['memo'];
                return false;
            }
        }
        $getLlPay["no_order"]         = $res['no_order'];
        $getLlPay["bank_card_number"] = $res['bank_card_number'];
        $getLlPay["name_goods"]       = $res['info_order'] ? $res['info_order'] : "还款";
        $getLlPay["info_order"]       = $res['info_order'];
        $getLlPay["money_order"]      = $res['money_order'];
        $getLlPay["id_no"]            = $res['id_card'];
        $getLlPay['apply_id']         = $map['order_number'];
        $getLlPay['create_time']      = $res['create_time'];
        $getLlPay['period']           = $param['days'];
        $getLlPay['type']             = $param['pay_type']; //还款方式 1：全额还款  2：延期  
        $getLlPay['project_id']       = $res['project_id'] ?: 0; //项目id
        $add = $this->allowField(true)->save($getLlPay);
        if(!$add){
            $this->error = '订单创建失败';
            return false;
        }

        $redis -> set($redisKey, $param['order_number'], 60); //加锁

        return $data;
	}

    /**
     * 支付后更新订单信息以及其他信息
     * @author   yhq <934797303@qq.com>
     * @DateTime 2017-10-11T15:05:52+0800
     * @param    array                   $notifyResp 回调的参数
     * @return   [type]                               [description]
     */
    public function payAfter( array $notifyResp=array(), $phone = '') {
        $this->startTrans();
        try {
            $ApplyModel    = new Apply();
            $UserInfoModel = new UserInfo();
            $order= $this->where('no_order',$notifyResp['merchantOutOrderNo'])->find();
            if($order['result_pay']=='SUCCESS') return true;

            $order_number = $order['apply_id'];
            $res = $ApplyModel->where('order_number',$order_number)->find();
            if(!$res){
                $this->error = '订单无效';
                return false;
            }

            $actual_money       = empty($res['actual_money'])? '0' : $res['actual_money']; //实际还款金额
            $delay_money        = empty($res['delay_money'])? '0' : $res['delay_money'];   //总延期费用
            $appoint_time       = $res['appoint_time'];                                    //约定还款时间
            $cur_money          = empty($res['cur_money']) ? $res['money'] : $res['cur_money']; // 应还本金 2018/2/27
            $dataA['cur_money'] = $cur_money;

            $order = $this->where('no_order',$notifyResp['merchantOutOrderNo'])->find();
            //支付成功但数据库没操作成功,则处理订单信息、支付信息、用户状态
            if($notifyResp['payResult']=='1'&&$order['result_pay']!='SUCCESS'){  
                $now   = time();
                $dataU['update_time'] = date('Y-m-d H:i:s');
                $period = empty($order['period']) ? 7 : $order['period'];  //借款周期

                $notifyResp['money_order'] = isset($notifyResp['money_order'])? $notifyResp['money_order'] :json_decode($notifyResp['msg'],true)['payMoney']; //兼容汇潮


                if($order['type'] == 2){ //延期处理
                    $dataA['renewal_count'] = ++$res['renewal_count'];    //续期次数
                    //延期开始时间为 上次的约定归还时间  2018/1/8
                    // $dataA['appoint_time']  = date('Y-m-d H:i:s', strtotime($appoint_time) + $period*24*3600);  
                    
                      // 延期到什么时候  2018/3/23
                    if(strtotime(date("Y-m-d", strtotime($appoint_time))) > strtotime(date("Y-m-d"))){
                        $startTime = strtotime($appoint_time); 
                    }else{
                        $startTime = time();
                    }
                    $dataA['appoint_time'] = date("Y-m-d", $startTime + $period*24*3600);

                    $dataA['status']        = 12; //续贷
                    $dataA['delay_money']   = $delay_money + $notifyResp['money_order'];

                    // 延期7天 才扣除本金的20%  2017/3/8
                    if($period == 7){
                        $dataA['cur_money'] = formatMoney($cur_money - $cur_money * 0.2);
                        if($dataA['cur_money'] == $cur_money){ //特殊处理0.05
                            $dataA['cur_money'] = $dataA['cur_money'] - 0.01;
                        }
                        //展期
                        $dataA['zhangqi'] = 1;
                        $dataA['part_repay'] = formatMoney($res['part_repay'] + $cur_money * 0.2);
                    }
                }else{ //还款处理 
                    if($order['type'] == 3){ // 部分还款
                        $arr = $ApplyModel->loanMoney($res);
                        if($notifyResp['money_order'] == $arr['money_order']){ // 部分还款 一次性归还
                            $dataA['cur_money'] = 0;  //应还本金
                        }else{
                            // 应还本金 = 应还金额 - 此次支付费用 
                            $dataA['cur_money'] = $arr['money_order'] - $notifyResp['money_order'];
                            $dataA['part_date'] = date('Y-m-d H:i:s', $now);  //部分还款时间
                        }
                    }else{ //全额还款
                        $dataA['cur_money'] = 0;  //应还本金                    
                    }

                    //累加还款金额 3/9
                    $dataA['actual_money'] = $actual_money + $notifyResp['money_order'];  //实际还款金额
                }

                //应还本金为0时结束订单
                if($dataA['cur_money'] <= 0){ 
                    $dataA['status']    = 5; //申请单状态改为 还款成功5
                    $dataA['hk_time']   = date('Y-m-d H:i:s', $now);  //还款时间
                    $dataA['cur_money'] = 0;  //应还本金        
                    // 无逾期并且还款成功 自动升级档位
                    if($res['overdue_count']<1){
                        $dataU['max_money'] = $this->nextMoney($res);
                    }
                }

                $notifyResp['pay_time'] = date('Y-m-d H:i:s', $now);//支付时间
            }
            
            $notifyResp['pay_type'] = isset($notifyResp['pay_type'])? $notifyResp['pay_type']:  'D';
            $notifyResp['result_pay'] = 'SUCCESS';
            $notifyResp['acct_name']  = $res['name'];
            //如果用户填写了预留手机号 则更新
            if($phone)
            {
                (new UserBankCard)->updateDataByUId(['bind_mob' => $phone],$res['uid']);
            }
            $updateA = $ApplyModel->allowField(true)->save($dataA, ['order_number'=>$order_number]); 
            $updateU = $UserInfoModel->allowField(true)->save($dataU, ['uid'=>$res['uid']]);
            $updateO = $this->allowField(true)->save($notifyResp, ['no_order'=>$notifyResp['merchantOutOrderNo']]);
            if($updateA===false  || $updateO===false || $updateU===false) {
                $this->rollback();
                $this->error = '订单处理失败'.$updateA.$updateO.$updateU;
                return false;
            }
            $this->commit();
            return true;
        } catch(\Exception $e) {
            $this->rollback();
            $this->error = '订单处理异常';
            return false;
        }
    }

    /**
     * 支付记录
     * @author   yhq <934797303@qq.com>
     * @DateTime 2017-10-18T11:34:20+0800
     * @param    [type]                   $uid [description]
     * @return   [type]                        [description]
     */
    public function payRecord($page=1,$limit=10,$uid){
        $config         = model('common/SystemConfig')->getSysConfigList();
        $map['user_id'] = $uid;
        $order          = $this->where($map)->page($page,$limit)->order('id desc')->select();
        if(!$order){
            return [];
        }

        $order = modelo2array($order);
        foreach ($order as $key => $value) {
            //支付结果
            switch ($value['result_pay']) {
                case 'SUCCESS':
                    $order[$key]['result'] = '成功'; 
                    break;                
                case 'WAITING':
                    $order[$key]['result'] = '等待支付'; 
                    break;                
                case 'PROCESSING':
                    $order[$key]['result'] = '银行支付处理中'; 
                    break;                
                case 'REFUND':
                    $order[$key]['result'] = '退款'; 
                    break;                
                case 'FAILURE':
                    $order[$key]['result'] = '失败'; 
                    break;
                default:
                    $order[$key]['result'] = '等待支付'; 
                    break; 
            }
            //支付方式
            switch ($value['pay_type']) {                
                case 'D':
                    $order[$key]['pay_type'] = '银行卡';
                    break;                
                case 'XX':
                    $order[$key]['pay_type'] = '线下';
                    break;                
                default:
                    $order[$key]['pay_type'] = '无';
                    break;
            }
            //交易对象
            $order[$key]['company_name'] = $config['APP_COMPANY_NAME'];
            //处理空字符串
            foreach ($order[$key] as $k2 => $v2) {
                if(empty($v2)){
                    $order[$key][$k2] = '';
                }
            }
            //除去多余字段
            unset($order[$key]['id']);
            unset($order[$key]['acct_name']);
            unset($order[$key]['user_id']);
            unset($order[$key]['id_no']);
            unset($order[$key]['oid_partner']);
            unset($order[$key]['dt_order']);
            unset($order[$key]['oid_paybill']);
            unset($order[$key]['settle_date']);
            unset($order[$key]['bank_code']);
            unset($order[$key]['no_agree']);
            unset($order[$key]['id_type']);
            unset($order[$key]['fangkuan_aid']);
        }
        return $order;
    }

    /**
     * 创建订单2  给后台定时任务使用
     * @author   yhq <934797303@qq.com>
     * @Date 2017-09-29
     * @param    [type]                   $uid [description]
     * @return   [type]                        [description]
     */
    public function createorder2($param) {
        if(empty($param['pay_type']) || empty($param['order_number']) || empty($param['pay_money'])){
            $this->error = '缺少参数';
            return false;
        }
        
        // 逾期处理中 禁止支付
        $script = new Script;
        $order_number = $param['order_number'];
        $canCreatePayOrder = $script->canCreatePayOrder($order_number);
        if($canCreatePayOrder['code'] != 1){
            $this->error = $canCreatePayOrder['msg'];
            return false;
        }

        $ApplyModel = new Apply();
        $UserInfoModel = new UserInfo();
        $UserModel = new User();
        $map['order_number'] = $param['order_number'];
        $map['status'] = 3;
        $res = $ApplyModel->where($map)->find();
        if(!$res){
            $this->error = '暂无还款数据';
            return false;
        }
        $res = $res->toArray();
        // 限制当天申请还款
        if(date('Ymd',SYS_TIMESTAMP) == date('Ymd',strtotime($res['fk_time']))  && $param['pay_type']=='1'){
            $this->error="不足一日，请次日申请";
            return false;
        }
         //特殊情况 档位会变，正在查找原因中......
        if($res['money'] < $res['loan_out_money'])
        {
            $this->error = '订单异常，请联系客服';
            return false;
        }
        $reg_time = $UserModel->where('uid',$res['uid'])->value('reg_time'); //用户注册时间

        $res['reg_time'] = date('YmdHis',strtotime($reg_time)); //用户注册时间格式化
        $res['create_time'] = date('Y-m-d H:i:s');  //创建时间
        $res['order_number'] = $ApplyModel->order_number();

        $arr = $ApplyModel->loanMoney($res);
               

        // 订单号去重
        $count = $this->where('no_order', $arr['no_order'])->count();
        if($count>0){
            $this->error = '数据异常，请重试';
            return false;
        }

        $res['money_order'] = (string)$arr['money_order'];  //金额
        $res['info_order']  = $arr['info_order'];   //描述
        $res['no_order']    = $arr['no_order'];    //支付订单号

        if($param['pay_money'] != $res['money_order']){
            $this->error = '数据异常，请刷新页面重试';
            return false;
        }
        
        $UserInfo = $UserInfoModel->where('uid',$res['uid'])->field('rand_code')->find();
        $res['rand_code'] = $UserInfo['rand_code'];
        //富友支付  项目录入
        $re = $this->getFuiouProjectParam($res);
        $fuiouApi = new FuiouApi;
        $projectRes = $fuiouApi->project($re);
        $projectRes = json_decode($projectRes,true);
        //项目录入成功
        if($projectRes['ret'] == '0000')
        {
            $res['project_id'] = $projectRes['project_id'];
        }else{
            file_put_contents(LOGS_DIR_NAME."projectError.txt", '创建时间:'.date('Y-m-d H:i:s',time())." 结果:录入失败:".$projectRes['memo'].'---'.json_encode($re)."\n\n", FILE_APPEND);
            $this->error = $projectRes['memo'];
            return false;
        }
        $datas["no_order"]         = $res['no_order'];
        $datas["bank_card_number"] = $res['bank_card_number'];
        $datas["name_goods"]       = $res['info_order'] ? $res['info_order'] : "还款";
        $datas["info_order"]       = $res['info_order'];
        $datas["money_order"]      = $res['money_order'];
        $datas["id_no"]            = $res['id_card'];
        $datas['apply_id']         = $map['order_number'];
        $datas['create_time']      = $res['create_time'];
        $datas['period']           = $param['days'];
        $datas['type']             = 1;
        $datas['project_id']       = $res['project_id'] ?: 0; //项目id
        $datas['pay_type']         = 'DK'; //还款方式
        $add = $this->allowField(true)->save($datas);
        if(!$add){
            $this->error = '订单创建失败';
            return false;
        }
        return $datas;
    }

    /**
     * 提升额度（包括线上线下还款）
     * 提升到下一额度，需连续完成相应笔数订单（完成订单内不存在逾期）
     * ------------------------------------------
     * @param  array   $apply       申请单
     * @return string  $max_money   额度
     */
    public function nextMoney($apply)
    {
        $ApplyModel = new Apply;
        $UserInfoModel = new UserInfo;

        $userInfo  = $UserInfoModel->where('uid', $apply['uid'])->field('max_money')->find();
        $configAll = Db::name('config')->order('money desc')->field('money,count')->select();  // 所有档位 金额从高到低
        $max_money = empty($userInfo['max_money']) ? end($configAll)['money'] : $userInfo['max_money'];  // 原始额度
// $max_money = '22.5';
// $apply['money'] = '15';

        // 无逾期并且还款成功 自动升级额度
        if($apply['overdue_count'] < 1){  // 此单没有逾期
            foreach ($configAll as $key => $value) {
                if($apply['money'] == $value['money']){
                    $limit = $value['count'] - 1; //查询次数
                    break;
                }
            }
            
            // 查询最近几笔还款成功的申请单
            if($limit > 0){
                $map['uid'] = $apply['uid'];
                $map['status'] = 5;
                $applyArr = $ApplyModel
                    ->where($map)
                    ->field('id, money, overdue_count')
                    ->order('id desc')
                    ->limit($limit)
                    ->select();
                $applyArr = modelo2array($applyArr); 
            }

// $applyArr = [                   
//     [
//         'money' => '22.5',
//         'overdue_count' => 0
//     ],                
//     [
//         'money' => '22.5',
//         'overdue_count' => 0
//     ],
// ];
// dump($limit);
// dump($applyArr);
// dump($configAll);

            foreach ($configAll as $key => $value) { 
                $can = 0;
                if($apply['money'] == $value['money']){
                    $can += 1;
                }

                for ($i = 0; $i < $value['count']; $i++) {                     
                    if($applyArr[$i]['money'] == $value['money'] && $applyArr[$i]['overdue_count'] < 1){
                        $can += 1;
                    }
                }  

                if($can >= $value['count']){
                    if($key > 0 && $max_money < $configAll[$key-1]['money']){
                        $max_money = $configAll[$key-1]['money'];  // 新的额度
// echo "<br>提额到".$max_money;
                    }
                }
            }
        }

        return $max_money;
    }

    /**
     * 订单明细
     * @author cxr <1481746137@qq.com>
     * @param $param
     * @param $uid
     * @return bool|false|static[]
     */
    public function orderRecord($param,$uid){

        $orderNumber = $param['order_number'];
        if(empty($param['order_number']) ){
            $this->error = '缺少参数';
            return false;
        }
        $records = $this->field('no_order,create_time,result_pay,pay_type,type')
            ->where('apply_id',$orderNumber)
            ->select();
//        $records = self::all(['order_number'=>$orderNumber]);
        return $records;
    }
    /**
     * [getFuiouParam 获取富友项目参数]
     * @return [type] [description]
     */
    public function getFuiouProjectParam(array $param = [])
    {
        $data['orderno'] = $param['no_order'];
        $data['project_amt'] = $param['money_order'];
        $data['contract_nm'] = $param['order_number'];
        $data['project_deadline'] = 7;
        $data['bor_nm'] = $param['name'];
        $data['id_no'] = $param['id_card'];
        $data['card_no'] = $param['bank_card_number'];
        $data['mobile_no'] = $param['phone'];
        return $data;
    }

    /**
     * [允许支付类型]
     * @author cxr <1481746137@qq.com>
     * @param $paytype 支付类型
     * @return bool
     */
    public static function allowPayType($paytype){
        $allowPayType =  explode(',',config('ALLOW_PAY_TYPE'));
        if(in_array((string)$paytype,$allowPayType))
            return true;
        else
            return false;

    }

}